首先,來點名詞定義:
WMI 是微軟對 DMTF( Distributed Management Task Force,分布式管理任務組 )定義的 CIM 標準的實現。它提供了一組接口,允許腳本和應用程序在 Windows 環境中訪問管理信息。WMI 使用 DCOM( Distributed Component Object Model )協議進行通信,這在跨網絡或通過防火牆時可能會遇到限制。然而,這是專門為 Windows 操作系統設計的管理框架,只能在 Windows 上運行。
CIM 是一種開放標準,用於描述計算機系統的管理信息。PowerShell 3.0 引入了 CIM Cmdlet,它們使用 WS-Man(Web Services-Management)協議,這是一種基於 HTTP/HTTPS 的協議,具有更好的防火牆兼容性和跨平台支持。但 PowerShell 中的 CIM Cmdlet( 如 Get-CimInstance )在非 Windows 平台上並未實現。
特性 | CIM(通用資訊模型) | WMI(Windows 管理工具) |
---|---|---|
全稱 | Common Information Model | Windows Management Instrumentation |
標準 | 開放標準(由 DMTF 定義) | 微軟實現的 CIM 標準 |
通訊協定 | WS-Man(Web Services-Management,基於 HTTP/HTTPS) | DCOM(分散式元件物件模型) |
跨平台支援 | 是,適用於多種作業系統 | 否,僅限於 Windows |
防火牆友好性 | 高,使用標準的 HTTP/HTTPS 埠 | 低,可能需要開放特定的 DCOM 埠 |
效能和可靠性 | 高效,適合遠端管理和腳本執行 | 在複雜網路環境中效能可能下降 |
PowerShell Cmdlet | Get-CimInstance 、Invoke-CimMethod 等 |
Get-WmiObject 、Invoke-WmiMethod 等 |
支援的 PowerShell 版本 | PowerShell 3.0 及以上版本 | PowerShell 2.0 及更早版本 |
未來趨勢 | 被微軟推薦,作為未來發展的重點 | 逐漸被 CIM 取代 |
使用情境 | 現代化腳本、遠端管理、大規模部署 | 相容舊版系統和腳本,特定功能需要 |
開發與維護 | 積極開發和維護,持續添加新功能 | 維護較少,主要用於相容性 |
上面比較表針對跨平台支援這塊,CIM 是開放標準,但是在 PowerShell 中的實現目前主要是針對 Windows,因此當我參考 Learn/PowerShell/Chapter7 的範例,在 macOS 用 Get-Command
來搜尋目前 PowerShell 裡有哪些 WMI Cmdlet 及 CIM Cmdlet 時,是完全找不到的喔。
Get-Command -Noun WMI*
Get-Command -Module CimCmdlets
接下來我會在 Windows 環境底下執行 PowerShell 作為範例,讓我們以取得網路介面卡資訊的情境為範例:
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration
Get-WmiObject -Class Win32_NetworkAdapterConfiguration
書中在 Chapter 15 - 逐一處理多個物件 中提供了一個例子,當透過以 CIM 基礎下所撈取到的 CIM 物件如何
使用 Invoke-CimMethod
來執行 CIM 物件裡的方法。
目標是想要將電腦中所有的 Intel 網路介面卡啟用 DHCP 功能,但我的 lib 僅用一張 intel 網卡設定了固定 IP,因此我將條件改了一下,我想要將原本一個沒有在使用的網卡將其 DHCP 功能開啟( TAP-Windows Adapter V9 )。
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration
功能:Get-CimInstance 是 PowerShell 中的 Cmdlet,用於取得 CIM(Common Information Model,通用資訊模型)物件的實例。
用途:它允許你從 CIM 資料庫中檢索各種系統資訊,例如硬體、作業系統、網路設定等。
-ClassName
參數:指定要檢索的 CIM 類別名稱。
Win32\_NetworkAdapterConfiguration
:這是一個 CIM 類別,包含了關於網路介面卡(Network Adapter)配置的詳細資訊。
因為我們僅想要篩選 TAP-Windows Adapter V9 該網卡因此加入 -Filter
,另外,在 WMI 篩選語法中,% 代表萬用字元。
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "description like '%TAP%'"
當我們在管線中取得這些設定物件後,我們想要啓用它們的 DHCP,我們可能會先試著尋找一個名稱叫做 Enable-DHCP 的 cmdlet。但是遺憾的是,我們沒有找到它。因為它根本不存在。
我們的下一步,是看看這個物件本身是否含有啟用 DHCP 的方法。
而我們可以透過 Get-CimClass
這個 cmdlet 來確認是否有任何包含 DHCP 關鍵字的方法:
(Get-CimClass Win32_NetworkAdapterConfiguration).CimClassMethods
可以看到有一個名稱為 EnableDHCP 的方法,開始使用它吧!
當我知道 Win32_NetworkAdapterConfiguration 這個類別有 EnableDHCP 這個方法時,我第一個想到的方式就真的像書中所講的一樣,將 Get-CimInstance
的結果,透過 pipeline 傳遞後,使用該 method 接收,期望它會成功。
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "description like '%TAP%'" | EnableDHCP
書中詳細的說明了錯誤的原因及概念:
你無法將物件傳送給一個方法:你只能將它們傳送給一個 cmdlet。EnableDHCP 不是一個 PowerShell 的 cmdlet。它其實是直接附加在設定物件上的一個行為。
Invoke-CimMethod
接收 CIM 物件,並呼叫附加在上面的方法這個 Invoke-CimMethod
特地用來接收一整批 CIM 物件,而我們透過 Get-CimInstance
取得的 CIM 物件,透過 pipeline 傳遞給該 cmdlet 後,可以呼叫附加在這些物件上的其中一個方法:
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "description like '%TAP%'" | Invoke-CimMethod -MethodName EnableDHCP
而 Invoke-CimMethod
處理完後的輸出結果有兩項資訊,回傳值及執行該命令的電腦名稱(如果電腦名稱是空白的,代表在 localhost 上執行)。ReturnValue 的定義則需要透過 Win32_NetworkAdapterConfiguration 裡針對 EnableDHCP 這個 method 的說明頁面上去查找:
https://learn.microsoft.com/zh-tw/windows/win32/cimwin32prov/enabledhcp-method-in-class-win32-networkadapterconfiguration
像我這次的執行結果得到的回傳值為 84,其意義為 配接器上未啟用IP,所以 Enable DHCP 沒有成功。
Day 19 - 變數:存放資料的地方